home *** CD-ROM | disk | FTP | other *** search
/ Die Speccy' 97 / Die Speccy' 97.iso / amiga_system / the_aminet / util / boot / avwm.lzh / avwm-0.4 / jumptable.c < prev    next >
C/C++ Source or Header  |  1994-08-08  |  5KB  |  165 lines

  1. /*
  2.     InstallWedge, RemoveWedge and GetJumpTable were taken from
  3.     UnixDirsII (by Martin W. Scott, mws@castle.ed.ac.uk)
  4.     They are based on a method used in ISpy, a CBM-provided AmigaMail example.
  5. */
  6.  
  7. #include <dos.h>
  8. #include <signal.h>
  9. #include <exec/types.h>
  10. #include <exec/execbase.h>
  11. #include <exec/memory.h>
  12. #include <exec/semaphores.h>
  13. #include <string.h>
  14. #include <proto/exec.h>
  15.  
  16. /* The name this JumpTable/Semaphore will get. */
  17. UBYTE *JTName = "AVWM-WindowMonitor-JT";
  18.  
  19. #include "wbwm.h"
  20. #include "jumptable.h"
  21.  
  22. extern struct LVOTable LVOArray[NUMBEROFFUNCTIONS];
  23.  
  24. BOOL
  25. InstallWedge (VOID)
  26. {
  27.   struct JumpTable *jumptable;
  28.   ULONG *addressptr;
  29.   UCOUNT i, j;
  30.  
  31.   Forbid ();
  32.  
  33.   /* Get pointer to JumpTable. Create it if necessary */
  34.   if (jumptable = GetJumpTable (JTName))
  35.   {
  36.     /* Try to get exclusive lock on semaphore, in case it already existed. */
  37.     if (AttemptSemaphore ((struct SignalSemaphore *) jumptable))
  38.     {
  39.       /* Make sure nobody else has function addresses in the jumptable */
  40.       if (jumptable->jt_Owner == NULL)
  41.       {
  42.     jumptable->jt_Owner = FindTask (0);
  43.     /* Don't want to disable any longer than necessary */
  44.     Disable ();
  45.  
  46.     for (i = 2, j = 0; i < NUMBEROFFUNCTIONS * 6; i += 6, j++)
  47.     {
  48.       /* Replace addresses in the jumptable with my own. */
  49.       addressptr = (ULONG *) ((UBYTE *) jumptable->jt_Function + i);
  50.       (*((ULONG *) LVOArray[j].lt_oldFunction)) = (ULONG) * addressptr;
  51.       *addressptr = (ULONG) LVOArray[j].lt_newFunction;
  52.     }
  53.     Enable ();
  54.       } 
  55.       else
  56.     printf ("Already running.\n");
  57.       ReleaseSemaphore ((struct SignalSemaphore *) jumptable);
  58.     }
  59.     else
  60.       printf ("Can't lock table.\n");
  61.   }
  62.   else
  63.     printf ("Can't create jumptable\n");
  64.   Permit ();
  65.  
  66.   return ((BOOL) jumptable);
  67. }
  68.  
  69. BOOL
  70. RemoveWedge (VOID)
  71. {
  72.   struct JumpTable *jumptable;
  73.   ULONG *addressptr;
  74.   UCOUNT i, j;
  75.  
  76.   Forbid ();
  77.  
  78.   if (jumptable = GetJumpTable (JTName))
  79.   {
  80.     /* Check if this task owns this jumptable */
  81.     if (jumptable->jt_Owner == FindTask (0))
  82.     {
  83.       /* Get the semaphore exclusively.
  84.        * Depending on what got SetFunction ()'ed this could take some time.
  85.        * Also note that shared locks are used to indicate the code is
  86.        * being executed and that shared locks can jump ahead of queue'ed
  87.        * exclusive locks, adding to the waittime.
  88.        */
  89.       ObtainSemaphore ((struct SignalSemaphore *) jumptable);
  90.  
  91.       Disable ();
  92.  
  93.       /* Restore old pointers in jumptable */
  94.  
  95.       for (i = 2, j = 0; i < NUMBEROFFUNCTIONS * 6; i += 6, j++)
  96.       {
  97.         addressptr = (ULONG *) ((UBYTE *) jumptable->jt_Function + i);
  98.         *addressptr = (*((ULONG *) LVOArray[j].lt_oldFunction));
  99.       }
  100.       Enable ();
  101.  
  102.       jumptable->jt_Owner = NULL;
  103.       ReleaseSemaphore ((struct SignalSemaphore *) jumptable);
  104.     }
  105.   }
  106.   Permit ();
  107.  
  108.   return (TRUE);
  109. }
  110.  
  111. struct JumpTable *
  112. GetJumpTable (UBYTE * name)
  113. {
  114.   struct JumpTable *jumptable;
  115.   ULONG *addressptr;
  116.   UWORD *jmpinstr;
  117.   UBYTE *jtname;
  118.   UCOUNT i, j;
  119.  
  120.   /* Not really necessary to forbid again, just to indicate that I don't
  121.    * want another task to create the semaphore while I'm trying to do the
  122.    * same. Here GetJumpTable () is only called from InstallWedge (), so it
  123.    * will just bump the forbid count.
  124.    */
  125.   Forbid ();
  126.  
  127.   if (!(jumptable = (struct JumpTable *) FindSemaphore (name)))
  128.   {
  129.     if (jumptable = AllocMem (sizeof (struct JumpTable), MEMF_PUBLIC | MEMF_CLEAR))
  130.     {
  131.       if (jtname = AllocMem (strlen (name) + 1, MEMF_PUBLIC | MEMF_CLEAR))
  132.       {
  133.         for (i = 0, j = 0; i < NUMBEROFFUNCTIONS * 6; i += 6, j++)
  134.         {
  135.           jmpinstr = (UWORD *) ((UBYTE *) jumptable->jt_Function + i);
  136.           *jmpinstr = 0x4EF9;
  137.  
  138.           addressptr = (ULONG *) ((UBYTE *) jumptable->jt_Function + i + 2);
  139.           *addressptr = (ULONG) SetFunction (
  140.              (struct Library *) (*((ULONG *) LVOArray[j].lt_LibBase)),
  141.              LVOArray[j].lt_LVO,
  142.              (VOID *) ((UBYTE *) jumptable->jt_Function + i)
  143.           );
  144.         }
  145.         jumptable->jt_Semaphore.ss_Link.ln_Pri = 0;
  146.  
  147.         strcpy (jtname, name);
  148.         jumptable->jt_Semaphore.ss_Link.ln_Name = jtname;
  149.         AddSemaphore ((struct SignalSemaphore *) jumptable);
  150.       }
  151.       else {
  152.         FreeMem (jumptable, sizeof (struct JumpTable));
  153.         jumptable = NULL;
  154.       }
  155.     }
  156.   }
  157.   Permit ();
  158.  
  159.   /* If succeeded, you now have a jumptable which entries point to the original
  160.    * library functions. If another task SetFunction ()'ed one or more of those
  161.    * already, that task can never go away anymore.
  162.    */
  163.   return (jumptable);
  164. }
  165.